package com.dubbo.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.dubbo.common.ResponseUtil;
import com.dubbo.common.check.CheckUtil;
import com.dubbo.common.file.FileUtil;
import com.dubbo.common.http.RequestUtil;
import com.dubbo.common.http.ResponseEntity;
import com.dubbo.common.redis.RedisDao;
import com.dubbo.common.result.ResultInfo;
import com.dubbo.domain.User;
import com.dubbo.domain.dto.UserDto;
import com.dubbo.service.business.user.UserService;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.QRCodeWriter;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

/**
 * 登录处理器
 * 
 * @author chenwei
 * @date 2018年3月19日 下午5:27:03
 */
@Controller
@RequestMapping("/techincianLogin")
public class LoginController {

	@Value("${shiro.session.timeout}")
	private long userLife;

	@Value("${wx.getOpenId.api}")
	private String getOpenIdApi;

	@Value("${wx.appid}")
	private String appidWX;

	@Value("${wx.key}")
	private String keyWX;

	@Value("${user.prefixkey.redis}")
	private String technicianTicket;

	@Autowired
	private RedisDao redisDao;

	@Autowired
	private UserService userService;
	
	private static final String FILE_SUFFIX = "png";
	
	/**
	 * 微信用户第一次登录注册用户请求接口
	 *
	 * @author lihongwu
	 * 2018年12月14日 上午11:07:45
	 * @param userJson
	 * @param response
	 * @param request
	 * @return
	 */
	@PostMapping("/wechatLogin.wx")
	@ResponseBody
	public Map<String, Object> wechatLogin(
			String userJson,
			HttpServletResponse response,
			HttpServletRequest request){
		//防止重复登录
		Map<String, Object> checkRepeatLogin = this.checkRepeatLogin(request);
		if(checkRepeatLogin!=null) {
			return checkRepeatLogin;
		}
		UserDto userDto = JSON.parseObject(userJson,UserDto.class);
		return userService.registerUserByWechat(userDto, request, response);
	}
	
	
	/**
	 * 防止重复登录
	 *
	 * @author lihongwu
	 * 2018年12月14日 上午11:08:14
	 * @param request
	 * @return
	 */
	private Map<String, Object> checkRepeatLogin(HttpServletRequest request) {
		String key = request.getHeader(ResultInfo.USERTOKEN);
		if(!StringUtils.isNotBlank(key)) {
			return null;
		}
		boolean exist = redisDao.exist(key);
		if(exist) {
			String userJson = redisDao.get(key);
			redisDao.set(key, userJson, userLife);
			return ResponseUtil.ajaxCheckSuccess("ok",ResultInfo.USERTOKEN,key);
		}
		return null;
	}
	
	/**
	 * 获取openId
	 *
	 * @author lihongwu
	 * 2018年12月14日 上午11:08:18
	 * @param request
	 * @param code
	 * @return
	 * @throws Exception
	 */
	@PostMapping("/getOpenId.wx")
	@ResponseBody
	public Map<String, Object> getOpenId(HttpServletRequest request,String code) throws Exception{
		if(!StringUtils.isNotBlank(code)) {
			return ResponseUtil.ajaxCheckError("系统繁忙,请稍后重试!","code");
		}
		Map<String,String> map = new HashMap<>();
		map.put("appid", appidWX);
		map.put("secret", keyWX);
		map.put("js_code", code);
		map.put("grant_type", "authorization_code");
				
		ResponseEntity httpClientPost = RequestUtil.httpClientGet(getOpenIdApi,map,null);
		
		String content = httpClientPost.getContent();
		
		JSONObject result=JSONObject.parseObject(content);
		
		Object errcode = result.get("errcode");
		if(errcode!=null&&errcode!="") {
			return ResponseUtil.ajaxCheckError("error", result);
		}else {
			return ResponseUtil.ajaxCheckSuccess("ok", "openId", result.get("openid").toString());
		}
	}
	
	/**
	 * 注册
	 *
	 * @author lihongwu
	 * 2018年12月14日 上午11:08:30
	 * @param request
	 * @param phone
	 * @param code
	 * @param password
	 * @param repassword
	 * @return
	 * @throws Exception
	 */
	@PostMapping("/regist.wx")
	@ResponseBody
	public Map<String,Object> regist(HttpServletRequest request,
			String name,String phone, String code, String password,String repassword,String province,String city,String area,String shopName) throws Exception{
		String path = this.getClass().getResource("/fastdfs_client.conf").getPath();
		return userService.registUser(request,name,phone, code, password, repassword,province,city,area,shopName,path);
	}
	
	//手动生成用户二维码
	/*public static void main(String[] args) throws IOException {
		String path = LoginController.class.getResource("/fastdfs_client.conf").getPath();
		String qrCodePath = getQRCode(path, "F://","userIdf41d231a230f45cf9518b81e0e043cca", 300, 300);
		System.out.println(qrCodePath);
	}*/
	
	public static String getQRCode(
			String path,
			String LocalPath,
			String content, 
			int widthPix, 
			int heightPix) throws IOException {
		try {
			if (!StringUtils.isNotBlank(content)) {
				return null;
			}
			//进行base64编码
			//content = Base64.getEncoder().encodeToString(content.getBytes());
			// 配置参数
			Map<EncodeHintType, Object> hints = new HashMap<>();
			hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
			// 容错级别
			hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
			// 图像数据转换，使用了矩阵转换
			BitMatrix bitMatrix = new QRCodeWriter().encode(content, BarcodeFormat.QR_CODE, widthPix,
					heightPix, hints);
			int[] pixels = new int[widthPix * heightPix];
			// 下面这里按照二维码的算法，逐个生成二维码的图片，
			// 两个for循环是图片横列扫描的结果
			for (int y = 0; y < heightPix; y++) {
				for (int x = 0; x < widthPix; x++) {
					if (bitMatrix.get(x, y)) {
						pixels[y * widthPix + x] = 0xff000000;
					} else {
						pixels[y * widthPix + x] = 0xffffffff;
					}
				}
			}
			String fileName = UUID.randomUUID().toString().replaceAll("-", "");
			File file = new File(LocalPath+fileName+"."+FILE_SUFFIX);
			FileOutputStream fos = new FileOutputStream(file);
			MatrixToImageWriter.writeToStream(bitMatrix,FILE_SUFFIX,fos);
			byte[] fileToByte = FileUtil.fileToByte(LocalPath+fileName+"."+FILE_SUFFIX);
			//文件上传
			String uploadFile = FileUtil.uploadFile(path, fileToByte, "png");
			//删除本地文件
			file.deleteOnExit();
			fos.close();
			return uploadFile;
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}
	
	/**
	 * 注册(小程序端)
	 *
	 * @author lihongwu
	 * 2018年12月14日 上午11:08:30
	 * @param request
	 * @param phone
	 * @param code
	 * @param password
	 * @param repassword
	 * @return
	 * @throws Exception
	 */
	@PostMapping("/registInWx.wx")
	@ResponseBody
	public Map<String,Object> registInWx(HttpServletRequest request,
			String openId,String name,String phone, String code, String password,String repassword,String province,String city,String area,String shopName) throws Exception{
		String path = this.getClass().getResource("/fastdfs_client.conf").getPath();
		return userService.registInWx(request,openId,name,phone, code, password, repassword,province,city,area,shopName,path);
	}
	
	/**
	 * 登录
	 *
	 * @author lihongwu
	 * 2018年12月14日 上午11:08:38
	 * @param request
	 * @param phone
	 * @param password
	 * @param registrationId  设备id
	 * @return
	 * @throws Exception
	 */
	@PostMapping("/login.wx")
	@ResponseBody
	public Map<String,Object> login(HttpServletRequest request,
			String phone,String password,String registrationId) throws Exception{
		//CheckUtil.checkOline3(request);
		return userService.login(phone,password,registrationId);
	}
	
	/**
	 * 登录(小程序端)
	 *
	 * @author lihongwu
	 * 2018年12月14日 上午11:08:38
	 * @param request
	 * @param phone
	 * @param password
	 * @return
	 * @throws Exception
	 */
	@PostMapping("/loginInWx.wx")
	@ResponseBody
	public Map<String,Object> loginInWx(HttpServletRequest request,String openId,
			String phone,String password) throws Exception{
		//CheckUtil.checkOline3(request);
		return userService.loginInWx(openId,phone,password);
	}
	
	/**
	 * 修改密码
	 *
	 * @author lihongwu
	 * 2018年12月14日 上午11:08:44
	 * @param request
	 * @param phone
	 * @param code
	 * @param password
	 * @param repassword
	 * @return
	 * @throws Exception
	 */
	@PostMapping("/resetPassword.wx")
	@ResponseBody
	public Map<String,Object> resetPassword(HttpServletRequest request,
			String phone,String code,String password,String repassword) throws Exception{
		User user = (User) CheckUtil.checkOline3(request);
		return userService.resetPassword(user,phone,code,password,repassword);
	}
	
	/**
	 * 找回密码
	 *
	 * @author lihongwu
	 * 2018年12月14日 上午11:08:44
	 * @param request
	 * @param phone
	 * @param code
	 * @param password
	 * @param repassword
	 * @return
	 * @throws Exception
	 */
	@PostMapping("/resetPassword")
	@ResponseBody
	public Map<String,Object> resetPasswordInAPP(HttpServletRequest request,
			String phone,String code,String password,String repassword) throws Exception{
		return userService.resetPasswordInApp(phone,code,password,repassword);
	}
	/**
	 * 修改或者绑定手机号
	 * 
	 * @author wujunyuan
	 * @date 2019年1月2日  下午5:21:34
	 * @param request
	 * @param phone 新手机号码
	 * @param code 验证码
	 * @param password 修改时加多一个password字段
	 * @return
	 * @throws Exception
	 */
	@PostMapping("/changePhone.wx")
	@ResponseBody
	public Map<String,Object> changePhone(HttpServletRequest request,
			String phone, String code,String password) throws Exception{
		User user = (User)CheckUtil.checkOline3(request);
		return userService.changePhone(request,user,phone,code,password);
	}
	
	/**
	 * 修改手机号
	 *
	 * @author lihongwu
	 * 2019年1月3日 上午9:57:27
	 * @param request
	 * @param phone
	 * @param code
	 * @param password
	 * @return
	 * @throws Exception
	 */
	/*@PostMapping("/resetPhone")
	@ResponseBody
	public Map<String,Object> resetPhone(HttpServletRequest request,
			String phone,String code,String password) throws Exception{
		User user = (User)CheckUtil.checkOline3(request);
		return userService.resetPhone(user,phone,code,password);
	}*/

	/**
	 *获取用户手机号码 
	 * @author wujunyuan
	 * @date 2019年1月2日  下午5:34:26
	 * @param request
	 * @return
	 * @throws Exception
	 */
	@PostMapping("/getUserPhone.wx")
	@ResponseBody
	public Map<String,Object> getUserPhone(HttpServletRequest request) throws Exception{
		User user = (User)CheckUtil.checkOline3(request);
		return userService.getUserPhone(request,user);
	}
	
}
